package Server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import utils.PropertiesUtils;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 电表数据采集监听服务-netty NIO
 * 
 * @author ack @date Oct 27, 2019
 *
 */
public class Server extends Thread {

	private static Logger log = LoggerFactory.getLogger(Server.class);

	/**
	 * key存放equId(ip:port)，value存放ctx；保证线程安全使用ConcurrentHashMap
	 */
	public static ConcurrentHashMap<String, ChannelHandlerContext> connectedEquId2Ctx = new ConcurrentHashMap<String, ChannelHandlerContext>();
	
	@Override
	public void run() {

		EventLoopGroup pGroup = new NioEventLoopGroup(); // 一组线程负责用于处理Client端的连接请求
		EventLoopGroup cGroup = new NioEventLoopGroup(); // 另一组线程负责信息的交互
		ServerBootstrap b = new ServerBootstrap(); // 辅助工具类，用于服务器通道的一系列配置

		b.group(pGroup, cGroup).channel(NioServerSocketChannel.class) // 指定NIO的模式
//                .option(ChannelOption.SO_BACKLOG,1024)   // 设置tcp缓存区
//                .option(ChannelOption.SO_SNDBUF,32*1024) // 设置发送缓冲的大小
//                .option(ChannelOption.SO_RCVBUF,32*1024) // 设置接收缓冲的大小
//                .option(ChannelOption.SO_KEEPALIVE,true)  // 保持连接
				.childHandler(new ChannelInitializer<SocketChannel>() {
					@Override
					protected void initChannel(SocketChannel sc) throws Exception {
						sc.pipeline().addLast(new ServerHandler()); // 配置具体数据接收方法的处理
					}
				});

		int port = Integer.parseInt(PropertiesUtils.getProperty("server.port", "6000"));

		try {
			ChannelFuture cf1 = b.bind(port).sync();
			log.info("#采集监听服务-启动结束，#线程：[{}],#端口:[{}]", Thread.currentThread().getName(), port);
			cf1.channel().closeFuture().sync(); // 等待关闭，异步，阻塞当前线程
			pGroup.shutdownGracefully(); // 清空线程池
			cGroup.shutdownGracefully();
		} catch (Exception e) {
			log.error("#port:[{}] has been used!!!", port);
		}

	}
}
